package com.qiantu.phone.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;

import com.qiantu.phone.R;
import com.qiantu.phone.app.AppApplication;

/**
 * @ClassName KHCurtainSeek
 * @Description TODO
 * @Author ShiJunqiang
 * @Date 2021/6/11 21:38
 * @Version 1.0
 */
public class KHCurtainSeek extends View {
    private int gapWidth;
    private ClipDrawable mLeftDrawable;
    private ClipDrawable mRightDrawable;
    private Drawable mLeftDragDrawable;
    private Drawable mRightDragDrawable;
    private Drawable backgroundDrawable;
    private Rect mLeftRect;
    private Rect mRightRect;
    private boolean isReadyDrag;
    private int isDragArea;
    public int mTrackLength;//轨道长度
    public Rect mRootRect;
    public int mMax = 100;
    public int mProgress = 0;
    protected OnChangeListener mOnChangeListener;
    public int clickThreshold;
    public final int CAN_DRAG_TIME = 0;
    private int topLineHeight;
    private int bottomHeight;
    private int curtainHeight;
    private int leftCurtainMarginLeft;
    private int curtainMarginTop;
    private int rightCurtainMarginRight;
    private float progressTextSize;
    private int progressTextColor;
    private Paint mPaint;
    private Paint mTextPaint;
    private RectF topLineRectF;
    private Rect leftDragRect;
    private Rect rightDragRect;
    private Rect bgRect;
    private int bgPaddingBottom;
    private int curtainLeftRightMinWidth;
    private int leftRightCurtainWidth;
    private boolean isNotSet;

    public KHCurtainSeek(Context context) {
        this(context, null);
    }

    public KHCurtainSeek(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public KHCurtainSeek(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public KHCurtainSeek(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView(context, attrs);
    }

    public void initView(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.KHCurtainSeek);
        mLeftDrawable = (ClipDrawable) ta.getDrawable(R.styleable.KHCurtainSeek_left_drawable);
        mRightDrawable = (ClipDrawable) ta.getDrawable(R.styleable.KHCurtainSeek_right_drawable);
        mLeftDragDrawable = ta.getDrawable(R.styleable.KHCurtainSeek_left_drag_drawable);
        backgroundDrawable = ta.getDrawable(R.styleable.KHCurtainSeek_background_drawable);
        mRightDragDrawable = ta.getDrawable(R.styleable.KHCurtainSeek_right_drag_drawable);
        progressTextColor = ta.getColor(R.styleable.KHCurtainSeek_progress_text_color, AppApplication.getInstance().getThemeColor(R.attr.secondaryColor6));
        progressTextSize = dp2px(16);
        ta.recycle();
//        gapWidth = dp2px(0f);
//        gapWidth = gapWidth == 0 ? 1 : gapWidth;
        mRootRect = new Rect();
        topLineHeight = dp2px(20);
        bottomHeight = dp2px(48);
        leftCurtainMarginLeft = dp2px(12);
        curtainMarginTop = dp2px(8);
        rightCurtainMarginRight = dp2px(12);
        curtainHeight = Math.max(mLeftDrawable.getIntrinsicHeight(), mRightDrawable.getIntrinsicHeight());

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
        topLineRectF = new RectF();
        bgRect = new Rect();
        bgPaddingBottom = dp2px(8);
        leftDragRect = new Rect();
        rightDragRect = new Rect();
        curtainLeftRightMinWidth = dp2px(29f);
        clickThreshold = dp2px(3);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int dw = getMeasuredWidth();
        int dh = curtainHeight + curtainMarginTop + bottomHeight;
        mRootRect.left = 0;
        mRootRect.top = 0;
        mRootRect.right = dw;
        mRootRect.bottom = dh;
        setMeasuredDimension(dw, dh);
        leftRightCurtainWidth = (int) (mRootRect.width() / 2f - gapWidth + 0.5f);
        mTrackLength = leftRightCurtainWidth - curtainLeftRightMinWidth - leftCurtainMarginLeft;
        mLeftRect = new Rect(leftCurtainMarginLeft, curtainMarginTop, leftRightCurtainWidth, curtainHeight + curtainMarginTop);
        mRightRect = new Rect(mRootRect.width() - leftRightCurtainWidth, curtainMarginTop, mRootRect.width() - rightCurtainMarginRight, curtainHeight + curtainMarginTop);
        mLeftDrawable.setBounds(mLeftRect);
        mRightDrawable.setBounds(mRightRect);
        topLineRectF.left = 0;
        topLineRectF.top = 0;
        topLineRectF.right = dw;
        topLineRectF.bottom = topLineHeight;
        bgRect.left = mLeftRect.left;
        bgRect.top = mLeftRect.top;
        bgRect.right = mRightRect.right;
        bgRect.bottom = mLeftRect.bottom - bgPaddingBottom;
        leftDragRect.left = mLeftRect.right - mLeftDragDrawable.getIntrinsicWidth() / 2;
        leftDragRect.top = (int) ((mLeftRect.height() - mLeftDragDrawable.getIntrinsicHeight()) / 2f);
        leftDragRect.right = mLeftRect.right + mLeftDragDrawable.getIntrinsicWidth() / 2;
        leftDragRect.bottom = (int) ((mLeftRect.height() + mLeftDragDrawable.getIntrinsicHeight()) / 2f);

        rightDragRect.left = mRightRect.left - mRightDragDrawable.getIntrinsicWidth() / 2;
        rightDragRect.top = (int) ((mRightRect.height() - mRightDragDrawable.getIntrinsicHeight()) / 2f);
        rightDragRect.right = mRightRect.left + mRightDragDrawable.getIntrinsicWidth() / 2;
        rightDragRect.bottom = (int) ((mRightRect.height() + mRightDragDrawable.getIntrinsicHeight()) / 2f);
        mLeftDragDrawable.setBounds(leftDragRect);
        mRightDragDrawable.setBounds(rightDragRect);
    }

    @Override
    protected void onDraw(Canvas canvas) {
//        if (isReadyDrag) {
//            mLeftDrawable.setAlpha(230);
//            mRightDrawable.setAlpha(230);
//        } else {
//            mLeftDrawable.setAlpha(255);
//            mRightDrawable.setAlpha(255);
//        }
//        if (mProgress < 100) {
////            mPaint.setShader(mLinearGradient);
//            mPaint.setShadowLayer(dp2px(12), 0, dp2px(6), 0x2225334b);
////            canvas.drawRect(bgRect.left, bgRect.bottom - bottomHeight * 2, bgRect.right, getHeight(), mPaint);
//        }
//        mPaint.setColor(0xffffffff);
//        canvas.drawRect(bgRect, mPaint);
        backgroundDrawable.setBounds(bgRect);
        backgroundDrawable.draw(canvas);
        float currentCurtainWidth = getCurrentCurtainWidth();
        float level = currentCurtainWidth / mLeftRect.width();
        mLeftDrawable.setLevel((int) (level * 10000));
        mRightDrawable.setLevel((int) (level * 10000));
//        mLeftRect.right = (int) (getRatio() * leftRightCurtainWidth);
//        mRightRect.left = (int) (mRootRect.width() - getRatio() * leftRightCurtainWidth);
//        mLeftDrawable.setBounds(mLeftRect);
//        mRightDrawable.setBounds(mRightRect);
        mLeftDrawable.draw(canvas);
        mRightDrawable.draw(canvas);
//        if(currentCurtainWidth == mLeftRect.width()){
            leftDragRect.left = (int) (leftCurtainMarginLeft + currentCurtainWidth - mLeftDragDrawable.getIntrinsicWidth() / 2);
            leftDragRect.right = (int) (leftCurtainMarginLeft + currentCurtainWidth + mLeftDragDrawable.getIntrinsicWidth() / 2);
            rightDragRect.left = (int) (mRootRect.width() - currentCurtainWidth - rightCurtainMarginRight) - mRightDragDrawable.getIntrinsicWidth() / 2;
            rightDragRect.right = (int) (mRootRect.width() - currentCurtainWidth - rightCurtainMarginRight) + mRightDragDrawable.getIntrinsicWidth() / 2;
            mLeftDragDrawable.setBounds(leftDragRect);
            mRightDragDrawable.setBounds(rightDragRect);
            mLeftDragDrawable.draw(canvas);
            mRightDragDrawable.draw(canvas);
//        }
        mPaint.setColor(AppApplication.getInstance().getThemeColor(R.attr.themeColor));
        mPaint.setShadowLayer(0, 0, 0, 0);
        canvas.drawRoundRect(topLineRectF, topLineHeight, topLineHeight, mPaint);

        //画进度文字
        String progressText = null;
        if (isNotSet) {
            progressText = getResources().getString(R.string.not_set);
        } else {
            progressText = (100 - mProgress) + "%";
        }
        mTextPaint.setTextSize(progressTextSize);
        int textX = (int) (getWidth() - mTextPaint.measureText(progressText)) / 2;
        mTextPaint.setColor(progressTextColor);
        canvas.drawText(progressText, textX, getHeight() - mTextPaint.getFontMetrics().bottom, mTextPaint);
    }

    public void setProgress(int value) {
        mProgress = value;
        isNotSet = false;
        correctProgress();
        invalidate();
    }

    public void isNotSet(boolean isNotSet) {
        this.isNotSet = isNotSet;
        mProgress = 0;
        invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) return true;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                markDownEvent(event);
                checkDragArea(true);
                break;
            case MotionEvent.ACTION_MOVE:
                if (isReadyDrag) {
                    getParent().requestDisallowInterceptTouchEvent(true);
                    updateDrag(event);
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                float upX = event.getX();
                float upY = event.getY();
                getParent().requestDisallowInterceptTouchEvent(false);
                if (mOnChangeListener != null && isReadyDrag) {
                    playSoundEffect(SoundEffectConstants.CLICK);
                    mOnChangeListener.onValueChanged(mProgress);
                }
//                if (!isReadyDrag && Math.abs(mDownEvent.downPositionY - event.getY()) < SLID_THRESHOLD) {
                float clickDistance = (float) Math.sqrt(Math.pow(Math.abs(upX - mDownEvent.downPositionX), 2) + Math.pow(Math.abs(upY - mDownEvent.downPositionY), 2));
                if (clickDistance <= clickThreshold) {
                    playSoundEffect(SoundEffectConstants.CLICK);
                    updateClick(event);
                    invalidate();
                }
                isReadyDrag = false;
                isDragArea = 0;
                isNotSet = false;
                break;
        }
        return true;
    }

    private void updateClick(MotionEvent event) {
        int div;
        if (event.getX() <= mRootRect.width() / 2.0f) {
            div = (int) (event.getX() - leftCurtainMarginLeft - curtainLeftRightMinWidth);
        } else {
            div = (int) (mRootRect.width() - event.getX() - rightCurtainMarginRight - curtainLeftRightMinWidth);
        }
        div = div < 0 ? 0 : div;
        int progress = (int) track2progress(div);
        if (progress < mMax * 0.05f) progress = 0;
        if (progress > mMax * 0.9f) progress = mMax;
        mProgress = progress;
        if (mOnChangeListener != null) {
            mOnChangeListener.onProgressChanged(mProgress);
            mOnChangeListener.onValueChanged(mProgress);
        }
    }

    private void updateDrag(MotionEvent event) {
        int track = (int) (event.getX() - mDownEvent.downPositionX);
        if (isDragArea == 2) {
            track = -track;
        }

        mProgress = mDownEvent.progress + (int) track2progress(track);
        correctProgress();
        if (mOnChangeListener != null) {
            mOnChangeListener.onProgressChanged(mProgress);
        }
        isNotSet = false;
        invalidate();
    }

    /**
     * 检查拖拉区域
     *
     * @param isAllProgress 是否是进度的全部区域
     */
    private void checkDragArea(boolean isAllProgress) {
        if (isAllProgress) {
//            if (mLeftRect.contains((int) mDownEvent.downPositionX, (int) mDownEvent.downPositionY)) {
            float currentCurtainWidth = getCurrentCurtainWidth();
            if ((mDownEvent.downPositionX >= mLeftRect.left && mDownEvent.downPositionX <= currentCurtainWidth + leftCurtainMarginLeft
                    && mDownEvent.downPositionY >= mLeftRect.top && mDownEvent.downPositionY <= mLeftRect.bottom) ||
                    (leftDragRect.contains((int) mDownEvent.downPositionX, (int) mDownEvent.downPositionY))) {
                isDragArea = 1;
//            } else if (mRightRect.contains((int) mDownEvent.downPositionX, (int) mDownEvent.downPositionY)) {
            } else if ((mDownEvent.downPositionX >= getWidth() - currentCurtainWidth - rightCurtainMarginRight && mDownEvent.downPositionX <= mRightRect.right
                    && mDownEvent.downPositionY >= mRightRect.top && mDownEvent.downPositionY <= mRightRect.bottom) ||
                    (rightDragRect.contains((int) mDownEvent.downPositionX, (int) mDownEvent.downPositionY))) {
                isDragArea = 2;
            } else {
                isDragArea = 0;
            }
            if (isDragArea > 0) {
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (isDragArea > 0) {
                            isReadyDrag = true;
                            if (mOnChangeListener != null) mOnChangeListener.onStartTrackingTouch();
                        } else {
                            isReadyDrag = false;
                        }
                    }
                }, CAN_DRAG_TIME);
            }

        } else {
            //todo 指定区域拖动
        }
    }

    /**
     * 进度比例
     *
     * @return
     */
    protected float getRatio() {
        return mProgress * 1.0f / mMax;
    }

    /**
     * 计算当前窗帘显示的宽度
     *
     * @return
     */
    private float getCurrentCurtainWidth() {
        return curtainLeftRightMinWidth + getRatio() * mTrackLength;
    }

    /**
     * 拉动轨迹换算成progress
     *
     * @param track
     * @return
     */
    public float track2progress(int track) {
        return track * 1.0f / mTrackLength * mMax;
    }

    protected class ActEvent {
        int progress;
        long downTime;
        float downPositionX;
        float downPositionY;
    }

    protected ActEvent mDownEvent = new ActEvent();

    protected void markDownEvent(MotionEvent event) {
        mDownEvent.progress = mProgress;
        mDownEvent.downTime = event.getEventTime();
        mDownEvent.downPositionX = event.getX();
        mDownEvent.downPositionY = event.getY();
    }

    public void correctProgress() {
        if (mProgress >= mMax) {
            mProgress = mMax;
        }
        if (mProgress <= 0) {
            mProgress = 0;
        }
    }

    /**
     * 进度监听
     */
    public interface OnChangeListener {
        /**
         * 进度条的更新
         *
         * @param progress
         */
        public void onProgressChanged(int progress);

        /**
         * 开始拖动
         */
        public void onStartTrackingTouch();

        /**
         * 停止拖动 确认进度值
         */
        public void onValueChanged(int progress);
    }

    public void setOnChangeListener(OnChangeListener changeListener) {
        mOnChangeListener = changeListener;
    }

    /**
     * dp转px
     *
     * @param dp dp值
     * @return px值
     */
    public int dp2px(float dp) {
        return (int) (getResources().getDimension(R.dimen.dp_1) * dp);
    }
}
